#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "map.h"

// Initialisation de la structure de la carte
// - Allocation mémoire
// - Initialisation des informations
SMap * init_map(SCommManager * manager, unsigned int nbCell) {
	SMap * world = malloc(sizeof(SMap));
	
	if (world) {
		// Allocation de la mémoire
		world->size = nbCell;
		world->map = malloc(world->size * sizeof(STerritory));
		
		if (world->map) {
			// Mise a zero
			memset(world->map, 0, world->size * sizeof(STerritory));
			
			// Recuperation des donnees
			for (unsigned int i = 1; i <= nbCell; i++) {
				init_cell(manager, world, i);
			}
			return world;
		} else {
			fprintf(stderr, "In init_map : failed to allocate memory.\n");
			exit(-1);
		}
	} else {
		fprintf(stderr, "In init_map : failed to allocate memory.\n");
		exit(-1);
	}
}

void init_cell(SCommManager * manager, SMap * world, int id) {	
	SCell ** neighbor;
	// Territoire
	world->map[id-1].cell.idCell = id;
	manager->GetContentCell(id, &(world->map[id-1].cell.nature),
								&(world->map[id-1].idTeam),
								&(world->map[id-1].idUnit),
								&(world->map[id-1].u_type));
	
	// Voisins
	neighbor = (SCell **) manager->GetNeighborCell(id);
	// Calculer le nombre de voisins
	unsigned int count;
	for (count = 0; neighbor[count]; count++)
		;
	// Allouer la mémoire nécessaire
	world->map[id-1].count_adjacent = count;
	world->map[id-1].adjacent = malloc(count * sizeof(unsigned int));
	
	// Enregistrer l'id des voisins
	if (world->map[id-1].adjacent) {
		for (int j = 0 ; j < count; j++) {
			world->map[id-1].adjacent[j] = neighbor[j]->idCell;
		}
	} else {
		fprintf(stderr, "In init_cell : failed to allocate memory.\n");
		exit(-1);
	}
}

void update_map(SCommManager * manager, SMap * world) {
		for (int i = 0; i < world->size; i++) {
		manager->GetContentCell(i + 1, &(world->map[i].cell.nature),
								&(world->map[i].idTeam),
								&(world->map[i].idUnit),
								&(world->map[i].u_type));
	}
}

int compute_alliances(SMap * world, int * team, int * cell) {
	// TO DO
	return 0;
}

int getEmptyCentre(SMap * world, int idTeam) {
	for (int i = 0; i < world->size; i++) {
		if (world->map[i].cell.nature == CN_Center && world->map[i].idTeam == idTeam && world->map[i].idUnit == 0) {
			return world->map[i].cell.idCell;
		}
	}
	return -1;
}

void free_map(SMap * world) {
	for (int i = 0; i < world->size; i++) {
		free(world->map[i].adjacent);
	}
	free(world->map);
	free(world);
}

void print_map(SMap * map) {
	for (int i = 0; i < map->size; i++) {
		printf("Cell %d (", map->map[i].cell.idCell);
		
		switch (map->map[i].cell.nature) {
			case CN_Earth:
				printf("Terre) ");
				break;
			case CN_Water:
				printf("Mer) ");
				break;
			case CN_Center:
				printf("Centre) ");
				break;
			default:
				break;
		}
		
		printf("| Equipe : %d ", map->map[i].idTeam);
		
		if (map->map[i].idUnit > 0) {
			printf("| Unit : %d, Type : ", map->map[i].idUnit);
			switch (map->map[i].u_type) {
				case UT_Army:
					printf("Armée ");
					break;
				case UT_Fleet:
					printf("Flotte ");
					break;
				default:
					break;
			}
		}
		printf("| Voisins : [");
		for (int j = 0; j < map->map[i].count_adjacent; j++) {
			printf("%d ", map->map[i].adjacent[j]);
		}
		printf("]\n");
	}
}